package com.example.user.customviewdemo.drawing.matrix;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;

/**
 * Created by user on 2016/5/12.
 */
public class MatrixImageView extends ImageView {

    private Paint paint;
    private Path path;
    private Matrix matrix;


    public MatrixImageView(Context context) {
        super(context);
    }

    public MatrixImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

        paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(5);

        path = new Path();
        matrix = new Matrix();

    }

    public MatrixImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        path.moveTo(0,0);
        path.lineTo(getWidth(),0);
        path.lineTo(getWidth(),getHeight());
        path.lineTo(0,getHeight());
        path.close();

        canvas.drawPath(path,paint);

    }

   private float preX,preY;
   private float preDistance,preDegrees;
    private int mode = 0;
    private final int NOMORL = 0;
    private final int DRAG = 1;
    private final int ZOOM = 2;
    private final float MIN_DISTANCE = 10;
    private final float MIN_DEGREES = 5;

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getActionMasked()){
            case MotionEvent.ACTION_DOWN:
                preX = event.getX();
                preY = event.getY();
                mode = NOMORL;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                preDistance = getDistance(event);
                preDegrees = getDegrees(event);
                mode = ZOOM;
                break;
            case MotionEvent.ACTION_MOVE:
                if(event.getPointerCount() == 1 && mode == NOMORL) {
                    //控制平移
                    float dx = event.getX() - preX;
                    float dy = event.getY() - preY;
                    preX = event.getX();
                    preY = event.getY();
                        matrix.preTranslate(dx, dy);
                }else if(event.getPointerCount() == 2 && mode == ZOOM){
                    //控制缩放
                    float distance = getDistance(event);
                    if(distance > MIN_DISTANCE) {
                        PointF point = getMidPoint(event);
                        matrix.preScale(distance / preDistance, distance / preDistance);
                        preDistance = distance;
                    }
                    //控制旋转
                    float degrees = getDegrees(event);
                    if(degrees > MIN_DEGREES) {
                        matrix.preRotate(degrees - preDegrees);
                        preDegrees = degrees;
                    }
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                mode = NOMORL;
                break;
            case MotionEvent.ACTION_UP:
                preY = event.getY();
                preX = event.getX();
                break;
        }
        setImageMatrix(matrix);
        return true;
    }

    /**
     *  获取两点距离
     * @param event
     * @return
     */
    private float getDistance(MotionEvent event){
        float x0 = event.getX(0);
        float x1 = event.getX(1);
        float y0 = event.getY(0);
        float y1 = event.getY(1);

        return (float) Math.sqrt((x0 - x1)*(x0 - x1) + (y0 - y1)*(y0 - y1));
    }

    /**
     * 得到两点间连线和水平线的角度
     * @param event
     * @return
     */
    private float getDegrees(MotionEvent event){
        float x0 = event.getX(0);
        float x1 = event.getX(1);
        float y0 = event.getY(0);
        float y1 = event.getY(1);

        double radius = Math.atan2(y1 - y0,x1 - x0);
        return (float) Math.toDegrees(radius);
    }

    private PointF getMidPoint(MotionEvent event){
        float x0 = event.getX(0);
        float x1 = event.getX(1);
        float y0 = event.getY(0);
        float y1 = event.getY(1);
        PointF point = new PointF();
        point.set((x0 + x1)/2,(y0 + y1)/2);
        return point;
    }
}
